<!--
  - Copyright (C) 2018-2019
  - All rights reserved, Designed By www.joolun.com
  中赋能运维管理系统：
  ① 移除多余的 rep 为前缀的变量，让 message 消息更简单
  ② 代码优化，补充注释，提升阅读性
  ③ 优化消息的临时缓存策略，发送消息时，只清理被发送消息的 tab，不会强制切回到 text 输入
  ④ 支持发送【视频】消息时，支持新建视频
-->
<template>
	<el-tabs
		type="border-card"
		v-model="objData.type"
		@tab-click="handleClick"
	>
		<!-- 类型 1：文本 -->
		<el-tab-pane name="text">
			<span slot="label"><i class="el-icon-document"></i> 文本</span>
			<el-input
				type="textarea"
				:rows="5"
				placeholder="请输入内容"
				v-model="objData.content"
				@input="inputContent"
			/>
		</el-tab-pane>
		<!-- 类型 2：图片 -->
		<el-tab-pane name="image">
			<span slot="label"><i class="el-icon-picture"></i> 图片</span>
			<el-row>
				<!-- 情况一：已经选择好素材、或者上传好图片 -->
				<div
					class="select-item"
					v-if="objData.url"
				>
					<img
						class="material-img"
						:src="objData.url"
					/>
					<p
						class="item-name"
						v-if="objData.name"
					>
						{{ objData.name }}
					</p>
					<el-row class="ope-row">
						<el-button
							type="danger"
							icon="el-icon-delete"
							circle
							@click="deleteObj"
						></el-button>
					</el-row>
				</div>
				<!-- 情况二：未做完上述操作 -->
				<div v-else>
					<el-row style="text-align: center">
						<!-- 选择素材 -->
						<el-col
							:span="12"
							class="col-select"
						>
							<el-button
								type="success"
								@click="openMaterial"
							>
								素材库选择<i class="el-icon-circle-check el-icon--right"></i>
							</el-button>
							<el-dialog
								title="选择图片"
								:visible.sync="dialogImageVisible"
								width="90%"
								append-to-body
							>
								<wx-material-select
									:obj-data="objData"
									@selectMaterial="selectMaterial"
								/>
							</el-dialog>
						</el-col>
						<!-- 文件上传 -->
						<el-col
							:span="12"
							class="col-add"
						>
							<el-upload
								:action="actionUrl"
								:headers="headers"
								multiple
								:limit="1"
								:file-list="fileList"
								:data="uploadData"
								:before-upload="beforeImageUpload"
								:on-success="handleUploadSuccess"
							>
								<el-button type="primary">上传图片</el-button>
								<div
									slot="tip"
									class="el-upload__tip"
								>
									支持 bmp/png/jpeg/jpg/gif 格式，大小不超过 2M
								</div>
							</el-upload>
						</el-col>
					</el-row>
				</div>
			</el-row>
		</el-tab-pane>
		<!-- 类型 3：语音 -->
		<el-tab-pane name="voice">
			<span slot="label"><i class="el-icon-phone"></i> 语音</span>
			<el-row>
				<div
					class="select-item2"
					v-if="objData.url"
				>
					<p class="item-name">{{ objData.name }}</p>
					<div class="item-infos">
						<wx-voice-player :url="objData.url" />
					</div>
					<el-row class="ope-row">
						<el-button
							type="danger"
							icon="el-icon-delete"
							circle
							@click="deleteObj"
						></el-button>
					</el-row>
				</div>
				<div v-else>
					<el-row style="text-align: center">
						<!-- 选择素材 -->
						<el-col
							:span="12"
							class="col-select"
						>
							<el-button
								type="success"
								@click="openMaterial"
							>
								素材库选择<i class="el-icon-circle-check el-icon--right"></i>
							</el-button>
							<el-dialog
								title="选择语音"
								:visible.sync="dialogVoiceVisible"
								width="90%"
								append-to-body
							>
								<WxMaterialSelect
									:objData="objData"
									@selectMaterial="selectMaterial"
								></WxMaterialSelect>
							</el-dialog>
						</el-col>
						<!-- 文件上传 -->
						<el-col
							:span="12"
							class="col-add"
						>
							<el-upload
								:action="actionUrl"
								:headers="headers"
								multiple
								:limit="1"
								:file-list="fileList"
								:data="uploadData"
								:before-upload="beforeVoiceUpload"
								:on-success="handleUploadSuccess"
							>
								<el-button type="primary">点击上传</el-button>
								<div
									slot="tip"
									class="el-upload__tip"
								>
									格式支持 mp3/wma/wav/amr，文件大小不超过 2M，播放长度不超过 60s
								</div>
							</el-upload>
						</el-col>
					</el-row>
				</div>
			</el-row>
		</el-tab-pane>
		<!-- 类型 4：视频 -->
		<el-tab-pane name="video">
			<span slot="label"><i class="el-icon-share"></i> 视频</span>
			<el-row>
				<el-input
					v-model="objData.title"
					placeholder="请输入标题"
					@input="inputContent"
				/>
				<div style="margin: 20px 0"></div>
				<el-input
					v-model="objData.description"
					placeholder="请输入描述"
					@input="inputContent"
				/>
				<div style="margin: 20px 0"></div>
				<div style="text-align: center">
					<wx-video-player
						v-if="objData.url"
						:url="objData.url"
					/>
				</div>
				<div style="margin: 20px 0"></div>
				<el-row style="text-align: center">
					<!-- 选择素材 -->
					<el-col :span="12">
						<el-button
							type="success"
							@click="openMaterial"
						>
							素材库选择<i class="el-icon-circle-check el-icon--right"></i>
						</el-button>
						<el-dialog
							title="选择视频"
							:visible.sync="dialogVideoVisible"
							width="90%"
							append-to-body
						>
							<wx-material-select
								:objData="objData"
								@selectMaterial="selectMaterial"
							/>
						</el-dialog>
					</el-col>
					<!-- 文件上传 -->
					<el-col :span="12">
						<el-upload
							:action="actionUrl"
							:headers="headers"
							multiple
							:limit="1"
							:file-list="fileList"
							:data="uploadData"
							:before-upload="beforeVideoUpload"
							:on-success="handleUploadSuccess"
						>
							<el-button type="primary"
								>新建视频<i class="el-icon-upload el-icon--right"></i
							></el-button>
						</el-upload>
					</el-col>
				</el-row>
			</el-row>
		</el-tab-pane>
		<!-- 类型 5：图文 -->
		<el-tab-pane name="news">
			<span slot="label"><i class="el-icon-news"></i> 图文</span>
			<el-row>
				<div
					class="select-item"
					v-if="objData.articles"
				>
					<wx-news :articles="objData.articles" />
					<el-row class="ope-row">
						<el-button
							type="danger"
							icon="el-icon-delete"
							circle
							@click="deleteObj"
						/>
					</el-row>
				</div>
				<!-- 选择素材 -->
				<div v-if="!objData.content">
					<el-row style="text-align: center">
						<el-col :span="24">
							<el-button
								type="success"
								@click="openMaterial"
								>{{ newsType === '1' ? '选择已发布图文' : '选择草稿箱图文'
								}}<i class="el-icon-circle-check el-icon--right"></i
							></el-button>
						</el-col>
					</el-row>
				</div>
				<el-dialog
					title="选择图文"
					:visible.sync="dialogNewsVisible"
					width="90%"
					append-to-body
				>
					<wx-material-select
						:objData="objData"
						@selectMaterial="selectMaterial"
						:newsType="newsType"
					/>
				</el-dialog>
			</el-row>
		</el-tab-pane>
		<!-- 类型 6：音乐 -->
		<el-tab-pane name="music">
			<span slot="label"><i class="el-icon-service"></i> 音乐</span>
			<el-row>
				<el-col :span="6">
					<div class="thumb-div">
						<img
							style="width: 100px"
							v-if="objData.thumbMediaUrl"
							:src="objData.thumbMediaUrl"
						/>
						<i
							v-else
							class="el-icon-plus avatar-uploader-icon"
						></i>
						<div class="thumb-but">
							<el-upload
								:action="actionUrl"
								:headers="headers"
								multiple
								:limit="1"
								:file-list="fileList"
								:data="uploadData"
								:before-upload="beforeThumbImageUpload"
								:on-success="handleUploadSuccess"
							>
								<el-button
									slot="trigger"
									size="mini"
									type="text"
									>本地上传</el-button
								>
								<el-button
									size="mini"
									type="text"
									@click="openMaterial"
									style="margin-left: 5px"
									>素材库选择</el-button
								>
							</el-upload>
						</div>
					</div>
					<el-dialog
						title="选择图片"
						:visible.sync="dialogThumbVisible"
						width="80%"
						append-to-body
					>
						<wx-material-select
							:objData="{ type: 'image', accountId: objData.accountId }"
							@selectMaterial="selectMaterial"
						/>
					</el-dialog>
				</el-col>
				<el-col :span="18">
					<el-input
						v-model="objData.title"
						placeholder="请输入标题"
						@input="inputContent"
					/>
					<div style="margin: 20px 0"></div>
					<el-input
						v-model="objData.description"
						placeholder="请输入描述"
						@input="inputContent"
					/>
				</el-col>
			</el-row>
			<div style="margin: 20px 0"></div>
			<el-input
				v-model="objData.musicUrl"
				placeholder="请输入音乐链接"
				@input="inputContent"
			/>
			<div style="margin: 20px 0"></div>
			<el-input
				v-model="objData.hqMusicUrl"
				placeholder="请输入高质量音乐链接"
				@input="inputContent"
			/>
		</el-tab-pane>
	</el-tabs>
</template>

<script>
import WxNews from '@/views/mp/components/wx-news/main.vue';
import WxMaterialSelect from '@/views/mp/components/wx-material-select/main.vue';
import WxVoicePlayer from '@/views/mp/components/wx-voice-play/main.vue';
import WxVideoPlayer from '@/views/mp/components/wx-video-play/main.vue';

import { getAccessToken } from '@/utils/auth';

export default {
	name: 'wxReplySelect',
	components: {
		WxNews,
		WxMaterialSelect,
		WxVoicePlayer,
		WxVideoPlayer,
	},
	props: {
		objData: {
			// 消息对象。
			type: Object, // 设置为 Object 的原因，方便属性的传递
			required: true,
		},
		newsType: {
			// 图文类型：1、已发布图文；2、草稿箱图文
			type: String,
			default: '1',
		},
	},
	data() {
		return {
			tempPlayerObj: {
				type: '2',
			},

			tempObj: new Map().set(
				// 临时缓存，切换消息类型的 tab 的时候，可以保存对应的数据；
				this.objData.type, // 消息类型
				Object.assign({}, this.objData),
			), // 消息内容

			// ========== 素材选择的弹窗，是否可见 ==========
			dialogNewsVisible: false, // 图文
			dialogImageVisible: false, // 图片
			dialogVoiceVisible: false, // 语音
			dialogVideoVisible: false, // 视频
			dialogThumbVisible: false, // 缩略图

			// ========== 文件上传（图片、语音、视频） ==========
			fileList: [], // 文件列表
			uploadData: {
				accountId: undefined,
				type: this.objData.type,
				title: '',
				introduction: '',
			},
			actionUrl:
				`${window.location.protocol}//${window.location.host}/api` +
				'/admin-api/mp/material/upload-temporary',
			headers: { Authorization: 'Bearer ' + getAccessToken() }, // 设置上传的请求头部
		};
	},
	methods: {
		beforeThumbImageUpload(file) {
			const isType =
				file.type === 'image/jpeg' ||
				file.type === 'image/png' ||
				file.type === 'image/gif' ||
				file.type === 'image/bmp' ||
				file.type === 'image/jpg';
			if (!isType) {
				this.$message.error('上传图片格式不对!');
				return false;
			}
			const isLt = file.size / 1024 / 1024 < 2;
			if (!isLt) {
				this.$message.error('上传图片大小不能超过 2M!');
				return false;
			}
			this.uploadData.accountId = this.objData.accountId;
			return true;
		},
		beforeVoiceUpload(file) {
			// 校验格式
			const isType =
				file.type === 'audio/mp3' ||
				file.type === 'audio/mpeg' ||
				file.type === 'audio/wma' ||
				file.type === 'audio/wav' ||
				file.type === 'audio/amr';
			if (!isType) {
				this.$message.error('上传语音格式不对!' + file.type);
				return false;
			}
			// 校验大小
			const isLt = file.size / 1024 / 1024 < 2;
			if (!isLt) {
				this.$message.error('上传语音大小不能超过 2M!');
				return false;
			}
			this.uploadData.accountId = this.objData.accountId;
			return true;
		},
		beforeImageUpload(file) {
			// 校验格式
			const isType =
				file.type === 'image/jpeg' ||
				file.type === 'image/png' ||
				file.type === 'image/gif' ||
				file.type === 'image/bmp' ||
				file.type === 'image/jpg';
			if (!isType) {
				this.$message.error('上传图片格式不对!');
				return false;
			}
			// 校验大小
			const isLt = file.size / 1024 / 1024 < 2;
			if (!isLt) {
				this.$message.error('上传图片大小不能超过 2M!');
				return false;
			}
			this.uploadData.accountId = this.objData.accountId;
			return true;
		},
		beforeVideoUpload(file) {
			// 校验格式
			const isType = file.type === 'video/mp4';
			if (!isType) {
				this.$message.error('上传视频格式不对!');
				return false;
			}
			// 校验大小
			const isLt = file.size / 1024 / 1024 < 10;
			if (!isLt) {
				this.$message.error('上传视频大小不能超过 10M!');
				return false;
			}
			this.uploadData.accountId = this.objData.accountId;
			return true;
		},
		handleUploadSuccess(response, file, fileList) {
			if (response.code !== 0) {
				this.$message.error('上传出错：' + response.msg);
				return false;
			}

			// 清空上传时的各种数据
			this.fileList = [];
			this.uploadData.title = '';
			this.uploadData.introduction = '';

			// 上传好的文件，本质是个素材，所以可以进行选中
			let item = response.data;
			this.selectMaterial(item);
		},
		/**
		 * 切换消息类型的 tab
		 *
		 * @param tab tab
		 */
		handleClick(tab) {
			// 设置后续文件上传的文件类型
			this.uploadData.type = this.objData.type;
			if (this.uploadData.type === 'music') {
				// 【音乐】上传的是缩略图
				this.uploadData.type = 'thumb';
			}

			// 从 tempObj 临时缓存中，获取对应的数据，并设置回 objData
			let tempObjItem = this.tempObj.get(this.objData.type);
			if (tempObjItem) {
				this.objData.content = tempObjItem.content ? tempObjItem.content : null;
				this.objData.mediaId = tempObjItem.mediaId ? tempObjItem.mediaId : null;
				this.objData.url = tempObjItem.url ? tempObjItem.url : null;
				this.objData.name = tempObjItem.url ? tempObjItem.name : null;
				this.objData.title = tempObjItem.title ? tempObjItem.title : null;
				this.objData.description = tempObjItem.description ? tempObjItem.description : null;
				return;
			}
			// 如果获取不到，需要把 objData 复原
			// 必须使用 $set 赋值，不然 input 无法输入内容
			this.$set(this.objData, 'content', '');
			this.$delete(this.objData, 'mediaId');
			this.$delete(this.objData, 'url');
			this.$set(this.objData, 'title', '');
			this.$set(this.objData, 'description', '');
		},
		/**
		 * 选择素材，将设置设置到 objData 变量
		 *
		 * @param item 素材
		 */
		selectMaterial(item) {
			// 选择好素材，所以隐藏弹窗
			this.closeMaterial();

			// 创建 tempObjItem 对象，并设置对应的值
			let tempObjItem = {};
			tempObjItem.type = this.objData.type;
			if (this.objData.type === 'news') {
				tempObjItem.articles = item.content.newsItem;
				this.objData.articles = item.content.newsItem;
			} else if (this.objData.type === 'music') {
				// 音乐需要特殊处理，因为选择的是图片的缩略图
				tempObjItem.thumbMediaId = item.mediaId;
				this.objData.thumbMediaId = item.mediaId;
				tempObjItem.thumbMediaUrl = item.url;
				this.objData.thumbMediaUrl = item.url;
				// title、introduction、musicUrl、hqMusicUrl：从 objData 到 tempObjItem，避免上传素材后，被覆盖掉
				tempObjItem.title = this.objData.title || '';
				tempObjItem.introduction = this.objData.introduction || '';
				tempObjItem.musicUrl = this.objData.musicUrl || '';
				tempObjItem.hqMusicUrl = this.objData.hqMusicUrl || '';
			} else if (this.objData.type === 'image' || this.objData.type === 'voice') {
				tempObjItem.mediaId = item.mediaId;
				this.objData.mediaId = item.mediaId;
				tempObjItem.url = item.url;
				this.objData.url = item.url;
				tempObjItem.name = item.name;
				this.objData.name = item.name;
			} else if (this.objData.type === 'video') {
				tempObjItem.mediaId = item.mediaId;
				this.objData.mediaId = item.mediaId;
				tempObjItem.url = item.url;
				this.objData.url = item.url;
				tempObjItem.name = item.name;
				this.objData.name = item.name;
				// title、introduction：从 item 到 tempObjItem，因为素材里有 title、introduction
				if (item.title) {
					this.objData.title = item.title || '';
					tempObjItem.title = item.title || '';
				}
				if (item.introduction) {
					this.objData.description = item.introduction || ''; // 消息使用的是 description，素材使用的是 introduction，所以转换下
					tempObjItem.description = item.introduction || '';
				}
			} else if (this.objData.type === 'text') {
				this.objData.content = item.content || '';
			}
			// 最终设置到临时缓存
			this.tempObj.set(this.objData.type, tempObjItem);
		},
		openMaterial() {
			if (this.objData.type === 'news') {
				this.dialogNewsVisible = true;
			} else if (this.objData.type === 'image') {
				this.dialogImageVisible = true;
			} else if (this.objData.type === 'voice') {
				this.dialogVoiceVisible = true;
			} else if (this.objData.type === 'video') {
				this.dialogVideoVisible = true;
			} else if (this.objData.type === 'music') {
				this.dialogThumbVisible = true;
			}
		},
		closeMaterial() {
			this.dialogNewsVisible = false;
			this.dialogImageVisible = false;
			this.dialogVoiceVisible = false;
			this.dialogVideoVisible = false;
			this.dialogThumbVisible = false;
		},
		deleteObj() {
			if (this.objData.type === 'news') {
				this.$delete(this.objData, 'articles');
			} else if (this.objData.type === 'image') {
				this.objData.mediaId = null;
				this.$delete(this.objData, 'url');
				this.objData.name = null;
			} else if (this.objData.type === 'voice') {
				this.objData.mediaId = null;
				this.$delete(this.objData, 'url');
				this.objData.name = null;
			} else if (this.objData.type === 'video') {
				this.objData.mediaId = null;
				this.$delete(this.objData, 'url');
				this.objData.name = null;
				this.objData.title = null;
				this.objData.description = null;
			} else if (this.objData.type === 'music') {
				this.objData.thumbMediaId = null;
				this.objData.thumbMediaUrl = null;
				this.objData.title = null;
				this.objData.description = null;
				this.objData.musicUrl = null;
				this.objData.hqMusicUrl = null;
			} else if (this.objData.type === 'text') {
				this.objData.content = null;
			}
			// 覆盖缓存
			this.tempObj.set(this.objData.type, Object.assign({}, this.objData));
		},
		/**
		 * 输入时，缓存每次 objData 到 tempObj 中
		 *
		 * why？不确定为什么 v-model="objData.content" 不能自动缓存，所以通过这样的方式
		 */
		inputContent(str) {
			// 覆盖缓存
			this.tempObj.set(this.objData.type, Object.assign({}, this.objData));
		},
	},
};
</script>

<style lang="scss" scoped>
.public-account-management {
	.el-input {
		width: 70%;
		margin-right: 2%;
	}
}
.pagination {
	text-align: right;
	margin-right: 25px;
}
.select-item {
	width: 280px;
	padding: 10px;
	margin: 0 auto 10px auto;
	border: 1px solid #eaeaea;
}
.select-item2 {
	padding: 10px;
	margin: 0 auto 10px auto;
	border: 1px solid #eaeaea;
}
.ope-row {
	padding-top: 10px;
	text-align: center;
}
.item-name {
	font-size: 12px;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	text-align: center;
}
.el-form-item__content {
	line-height: unset !important;
}
.col-select {
	border: 1px solid rgb(234, 234, 234);
	padding: 50px 0px;
	height: 160px;
	width: 49.5%;
}
.col-select2 {
	border: 1px solid rgb(234, 234, 234);
	padding: 50px 0px;
	height: 160px;
}
.col-add {
	border: 1px solid rgb(234, 234, 234);
	padding: 50px 0px;
	height: 160px;
	width: 49.5%;
	float: right;
}
.avatar-uploader-icon {
	border: 1px solid #d9d9d9;
	font-size: 28px;
	color: #8c939d;
	width: 100px !important;
	height: 100px !important;
	line-height: 100px !important;
	text-align: center;
}
.material-img {
	width: 100%;
}
.thumb-div {
	display: inline-block;
	text-align: center;
}
.item-infos {
	width: 30%;
	margin: auto;
}
</style>
